package com.un.ebs.order.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.un.ebs.core.common.GroupListInfo;
import com.un.ebs.core.power.PowerResourcManager;
import com.un.ebs.memorial.dto.OrderWxPayResponse;
import com.un.ebs.order.domain.OrderAttr;
import com.un.ebs.order.domain.OrderExt;
import com.un.ebs.order.domain.OrderItemExt;
import com.un.ebs.order.domain.OrderReportExt;
import com.un.ebs.order.dto.*;
import com.un.ebs.order.enums.OrderStatusEnum;
import com.un.ebs.product.domain.ProductClassOrderAttrExt;
import com.un.ebs.product.dto.ProductClassOrderAttrVO;
import com.un.ebs.sys.dto.PersonnelDto;
import org.springframework.web.multipart.MultipartFile;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务类
 * </p>
 *
 * @author liubo
 * @since 2019-11-16
 */
public interface OrderService extends PowerResourcManager {

    /**
     * 创建订单
     *
     * @param req
     * @return
     */
    String add(OrderAddDto req);

    /**
     * 简易购买，客户与订单同时创建，不需要用户认证
     *
     * @param req
     * @return
     */
    String addSimple(OrderSimpleAddDto req);

    /**
     * 生成微信预支付单号
     *
     * @param id
     * @param openId
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     * @throws WxPayException
     */
    OrderWxPayResponse preWxPay(String id, String openId) throws NoSuchAlgorithmException, UnsupportedEncodingException, WxPayException;

    /**
     * 附加文件到订单明细中
     *
     * @param itemId 订单明细的主键
     * @param files  文件数据集合
     * @return 返回文件ID
     */
    List<String> addFile(String itemId, String attrId, List<MultipartFile> files);

    /**
     * 提交订单明细属性
     *
     * @param itemId
     */
    void submitFile(String itemId);

    /**
     * 撤销订单明细属性的提交状态
     *
     * @param itemId
     * @param desc
     */
    void cancelSubmitFile(String itemId, String desc);

    /**
     * 删除文件
     *
     * @param id
     */
    void removeFile(String id);

    /**
     * 修改订单
     *
     * @param req
     */
    void update(OrderUpdateDto req);

    /**
     * 修改订单项的数量和价格，只针对后付费商品
     *
     * @param req
     */
    void updateQtyAndPrice(OrderItemUpdateQtyAndPriceDto req);

    /**
     * 修改订单项的计划交付时间和价格
     *
     * @param req
     */
    void updatePlanDeliver(String orderId, List<OrderItemUpdateDto> req);

    /**
     * 未付款订单超过撤销。
     *
     * @param id
     */
    void timeOutCancel(String id);

    /**
     * 查询订单详情
     *
     * @param id
     * @return
     */
    OrderVo queryById(String id);

    /**
     * 查询订单集合
     *
     * @param createUserId
     * @param searchText
     * @param status
     * @param pageSize
     * @param pageIndex
     * @return
     */
    IPage<OrderExt> query(String createUserId, String searchText, OrderStatusEnum status, int pageSize, int pageIndex);

    /**
     * 查询订单明细
     *
     * @param searchText
     * @param status
     * @param pageSize
     * @param pageIndex
     * @return
     */
    IPage<OrderItemExt> queryItem(String searchText, OrderStatusEnum status, Integer pageSize, Integer pageIndex);

    /**
     * 查询指定的订单项
     *
     * @param itemId
     * @return
     */
    OrderItemExt queryItemById(String itemId);

    /**
     * 按订单ID查询所有项目
     *
     * @param id
     * @return
     */
    List<OrderItemExt> queryItemViewByOrderId(String id);

    /**
     * 按客户查询订单
     *
     * @param id
     * @return
     */
    List<OrderExt> queryByCustId(String id);

    /**
     * 按指定的创建用户做订单的状态统计
     *
     * @param id
     * @return
     */
    List<GroupListInfo<OrderVo>> queryStatusCountByUserId(String id);

    /**
     * 按客户查询所有订单
     *
     * @param ids
     * @return
     */
    List<OrderExt> queryByCustId(List<String> ids);

    /**
     * 查询计划交付项目，按次交付的订单项
     *
     * @return
     */
    List<OrderItemPlanDeliverDto> queryPlanDeliverItem(String searchText);

    List<OrderExt> queryByTrace(String id);

    /**
     * 查询计划交付项目，周期性的订单项
     *
     * @param searchText
     * @return
     */
    List<OrderItemPlanDeliverDto> queryPlanDeliverItemByTimePeriod(String searchText);

    /**
     * 查询可预约项目
     *
     * @param custId
     * @return
     */
    List<OrderItemBookByDto> queryBookRec(String custId);

    /**
     * 查询明阳山订单，按客户ID
     *
     * @param id
     * @return
     */
    OrderBzVo queryBzOrderByCustId(String id);

    /**
     * 查询所有超时未支付的订单
     *
     * @param pageSize
     * @param pageIndex
     * @return
     */
    IPage<OrderExt> queryPaymentTimeOut(int pageSize, int pageIndex);

    /**
     * 根据订单ID，查询订单明细中所有SKU的订单属性，前端需要根据此属性构建属性填写界面。
     *
     * @param id 订单ID
     * @return 订单属性集合
     */
    List<OrderAttrVo> queryOrderAttrByOrderId(String id);

    /**
     * 根据Sku查询订单属性
     *
     * @param id
     * @return
     */
    List<ProductClassOrderAttrExt> queryOrderAttrBySkuId(String id);

    /**
     * 根据Spu查询订单属性
     *
     * @param id
     * @return
     */
    List<ProductClassOrderAttrExt> queryOrderAttrBySpuId(String id);

    /**
     * 将输入参数结构化为 groupList VO对象集合
     *
     * @param list
     * @return
     */
    List<ProductClassOrderAttrVO> convertOrderAttrToGroupList(List<ProductClassOrderAttrExt> list);

    /**
     * @param list
     * @return
     */
    List<ProductClassOrderAttrVO> convertOrderAttrVoToGroupList(List<OrderAttrVo> list);

    /**
     * 记录通知
     *
     * @param id
     */
    void recordNotifyByCustId(String id);

    /**
     * @return
     */
//    List<OrderWaitNotify> queryWaitNotify();

    /**
     * 订单删除
     *
     * @param id
     */
    void delete(String id);

    /**
     * 整单提交
     *
     * @param id
     */
    void submit(String id);

    /**
     * 撤销提交
     *
     * @param id
     * @param remark
     */
    void submitCancel(String id, String remark);

    /**
     * 撤销，并退款
     *
     * @param id
     * @param remark
     * @param payDict
     * @param money
     */
    void submitCancel(String id, String remark, String payDict, Double money);

    /**
     * 整单受理
     *
     * @param id
     */
    void accept(String id);

    /**
     * 整单交付
     *
     * @param id
     */
    void deliver(String id);

    /**
     * 订单项交付
     *
     * @param itemId
     */
    void deliverItem(String itemId);

    void deliverItem(String itemId, Double qty, Double price);

    /**
     * 订单项交付
     *
     * @param orderId
     * @param itemID
     * @param qty
     * @param price
     */
    void deliverItem(String orderId, String itemID, Double qty, Double price);

    /**
     * 收款
     *
     * @param req
     */
    void payment(OrderPayDto req, String userId);

    /**
     * 退款
     *
     * @param req
     */
    void paymentBack(OrderPayDto req);

    /**
     * 订单提交后付款延期申请
     *
     * @param req
     */
    void expireApply(OrderExpireApplyDto req);

    /**
     * 订单支付延期申请审批
     *
     * @param req
     */
    void expireApplyAudit(OrderExpireApplyAuditDto req);

    /**
     * 订单折扣申请
     *
     * @param req
     */
    void discountApply(OrderDiscountApplyDto req);

    /**
     * 订单折扣审核
     *
     * @param req
     */
    void discountApplyAudit(OrderDiscountApplyAuditDto req);

    /**
     * 根据指定的ItemID，查询所有附件
     *
     * @param itemId
     * @return
     */
    List<OrderAttr> queryAttrByItem(String itemId);

    List<PersonnelDto> queryDiscountAuditPersonnel(String orderId, Double discountMoney);

    List<PersonnelDto> queryExpireAuditPersonnel();

    /**
     * 获取所有过期的订单
     *
     * @return
     */
    List<OrderExt> queryExpire();

    /**
     * 查询指定逝者的消费明细
     *
     * @param ids
     * @return
     */
    List<OrderItemByDefunct> queryItemByDefunct(String ids);

    IPage<OrderReportExt> querySaleReport(String searchText, Date start, Date end, Integer pageSize, Integer pageIndex);
}
